package crl.encrypt.ext
{
	import com.swfwire.decompiler.AsyncSWFReader;
	import com.swfwire.decompiler.SWFReaderContext;
	import com.swfwire.decompiler.abc.ABCByteArray;
	import com.swfwire.decompiler.abc.ABCReadResult;
	import com.swfwire.decompiler.data.swf.records.TagHeaderRecord;
	import com.swfwire.decompiler.data.swf.tags.SWFTag;
	import com.swfwire.decompiler.data.swf9.tags.DefineBinaryDataTag;
	import com.swfwire.decompiler.data.swf9.tags.DoABCTag;
	
	import crl.encrypt.ext.avm2.ExABCReader;
	import crl.encrypt.ext.tag.TagDoABCDeprecated;
	
	import flash.utils.ByteArray;
	
	public class ExAsyncSWFReader extends AsyncSWFReader
	{
		public function ExAsyncSWFReader()
		{
			super();
		}
		
		
		override protected function readTag(context:SWFReaderContext, header:TagHeaderRecord):SWFTag
		{
			var tag:SWFTag;
			switch(header.type)
			{
				case 76:
					tag = readSymbolClassTag(context, header);
					break;
				case 72:
					tag=readDoABCDeprecatedTag(context, header);
				case 82:
					tag = readDoABCTag(context, header);
					break;
				default:
					tag = readUnknownTag(context, header);
					break;
			}
			
			
			return tag;
		}
		
		override protected function readDoABCTag(context:SWFReaderContext, header:TagHeaderRecord):DoABCTag
		{
			var tag:DoABCTag = new DoABCTag();
			var nonABCData:uint = context.bytes.getBytePosition();
			tag.flags = context.bytes.readUI32();
			tag.name = context.bytes.readString();
			nonABCData = header.length - (context.bytes.getBytePosition() - nonABCData);
			var abcData:ByteArray = new ByteArray();
			if(nonABCData > 0)
			{
				context.bytes.readBytes(abcData, 0, nonABCData);
			}
			
			var abcReader:ExABCReader = new ExABCReader();
			var readResult:ABCReadResult = abcReader.read(new ABCByteArray(abcData));
			
			if(context.result.abcMetadata.length <= context.tagId)
			{
				context.result.abcMetadata.length = context.tagId + 1;
			}
			context.result.abcMetadata[context.tagId] = readResult.metadata;
			
			tag.abcFile = readResult.abcFile;
			
			return tag;
		}

		
		protected function readDoABCDeprecatedTag(context:SWFReaderContext, header:TagHeaderRecord):TagDoABCDeprecated{
			var tag:TagDoABCDeprecated = new TagDoABCDeprecated();
			var abcData:ByteArray = new ByteArray();
			context.bytes.readBytes(abcData,0,header.length);
			tag.data=abcData;
			
			var abcReader:ExABCReader = new ExABCReader();
			var readResult:ABCReadResult = abcReader.read(new ABCByteArray(abcData));
			
			if(context.result.abcMetadata.length <= context.tagId)
			{
				context.result.abcMetadata.length = context.tagId + 1;
			}
			context.result.abcMetadata[context.tagId] = readResult.metadata;
			
			tag.abcFile = readResult.abcFile;
			
			return tag;
		}
		
		
		
		override protected function readDefineBinaryDataTag(context:SWFReaderContext, header:TagHeaderRecord):DefineBinaryDataTag
		{
			var tag:DefineBinaryDataTag = new DefineBinaryDataTag();
			tag.characterId = context.bytes.readUI16();
			tag.reserved = context.bytes.readUI32();
			tag.data = new ByteArray();
			var length:int = header.length - 6;
			if(length > 0)
			{
				context.bytes.readBytes(tag.data, 0, length);
			}
			return tag;
		}
	}
}